package com.learning.spring.aop.advice.introduction;

import com.learning.spring.aop.advice.monitor.AopMonitor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;

/**
 * ClassName: AopIntroductionInterceptor
 * Description: 引介 Advice
 * 1. 引介 Advice 是一种比较特殊的Advice，它并不是在目标方法周围织入增强，而是为目标类创建新的方法与属性，所以引介的连接点是类级别的。
 * 2. 通过引介可以为目标类添加一个接口的实现。原来目标类没有实现某个接口，通过引介Advice可以为目标类创建实现某个接口的代理。
 * 3. Spring 定义了引介Advice 接口 IntroductionInterceptor 以及实现类 DelegatingIntroductionInterceptor。
 * <p>
 * 4. 回顾前面的例子，需要在业务类 AopService 中加入监控 AopMonitor，因为监控有可能会影响业务性能，所以是否启用监控应该是可控的，可以使用引介Advice实现。
 * <p>
 * Date: 2019/4/21 15:40 【需求编号】
 *
 * @author Sam Sho
 * @version V1.0.0
 */
public class AopIntroductionInterceptor extends DelegatingIntroductionInterceptor implements MonitorAble {

    /**
     * 线程特殊处理，如果不处理，则对象只能为 prototype（会影响性能）
     */
    private ThreadLocal<Boolean> monitorStatusMap = new ThreadLocal<>();

    @Override
    public void setMonitorActive(boolean active) {
        monitorStatusMap.set(active);
    }

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        Object invoke;

        if (monitorStatusMap.get() != null && monitorStatusMap.get()) {
            AopMonitor.start();
            invoke = super.invoke(mi);
            AopMonitor.end();
        } else {
            invoke = super.invoke(mi);
        }
        return invoke;
    }
}